#include "stdafx.h"
#include "ToyotaComm.h"
#include "ToyotaReadFile.h"
#include "ToyotaPJ.h"
#include "ToyotaSysP.h"
#include "ToyotaSpecFunc.h"
#include "ToyotaCDSF.h"






unsigned __int16 SendSpecCommand(tt_Token *token, SpecInfoSt *SpecBuf, int SpecIndex, int FinalSelID)
{
	CmdInfoSt *PCmdData; // r4
	size_t Len2; // r5
	int v9; // r1
	size_t tlen; // r8
	unsigned char *v11; // r0
	bool v12; // zf
	int toolID; // r2
	signed int v14; // r11
	int RecvLen; // r0
	bool v16; // zf
	int v17; // r1
	int v18; // r2
	unsigned char *v19; // r3
	unsigned __int16 result; // r0
	unsigned __int8 *v21; // r4
	unsigned __int8 *v22; // r0
	int v23; // r1
	int v24; // r0
	int tToolID; // [sp+Ch] [bp-5144h]
	_WORD v26[4]; // [sp+10h] [bp-5140h] BYREF
	unsigned __int8 v27[256]; // [sp+18h] [bp-5138h] BYREF
	unsigned __int8 v28[256]; // [sp+118h] [bp-5038h] BYREF
	unsigned __int8 RecvBuf[20000]; // [sp+218h] [bp-4F38h] BYREF
	unsigned __int8 pCmd[64]; // [sp+5038h] [bp-118h] BYREF

	memset(RecvBuf, 0, sizeof(RecvBuf));
	memset(v28, 0, 0xFFu);
	memset(v27, 0, 0xFFu);
	v26[2] = 0;
	*(_DWORD *)v26 = 0;
	PCmdData = (CmdInfoSt *)((char *)token + 0x102 * SpecIndex);
	Len2 = PCmdData[0xD].SysCmdBuf[1];
	v9 = Len2 ^ 0xFF;
	if (Len2 == 0xFF)
		v9 = 0;
	memset(&pCmd[PCmdData[0xD].SysCmdBuf[1]], 0, v9);
	qmemcpy(pCmd, &PCmdData[0xD].SysCmdBuf[2], Len2);
	SpecBuf->field_4C0 = pCmd[0];
	tlen = PCmdData[0xD].SysCmdBuf3[1];
	qmemcpy(v28, &PCmdData[0xD].SysCmdBuf3[2], tlen);
	qmemcpy(v27, &PCmdData[0xD].SysCmdBuf2[2], PCmdData[0xD].SysCmdBuf2[1]);
	GetSendCmdSearchIndex(
		*((unsigned __int16 *)token->SysInfoArr + 0x68D2 * token->SysListCanUseNum),
		Len2,
		pCmd,
		v26,
		token);
	v11 = &token->AreaCode + 0x35D98 * v26[0] + 0x102 * v26[1];
	if (v11[0x10E26] == 1)
	{
		v14 = (unsigned __int8)v11[0x10E5C];        // v11[0x10E5c]
		qmemcpy(RecvBuf, v11 + 0x10E5D, v14);
		goto LABEL_25;
	}
	if (v11[0x10E26])
	{
		LOWORD(v14) = 0xFFFF;
		goto LABEL_25;
	}
	v12 = Len2 == 2;
	if (Len2 == 2)
		v12 = token->unknowToolID == 0xFBE0;
	if (!v12)
	{
	LABEL_11:
		toolID = 0;
		goto LABEL_15;
	}
	toolID = 0;
	if (pCmd[0] <= 9u)
	{
		if (!pCmd[1])
		{
			toolID = token->ToolID;
			token->ToolID = 0xFBE0;
			goto LABEL_15;
		}
		goto LABEL_11;
	}
LABEL_15:
	tToolID = toolID;
	RecvLen = SendCmdAndGetReceive(RecvBuf, 20000, token, pCmd, Len2, (unsigned __int8)token->KwpCmdModeVal, 0);
	v16 = Len2 == 2;
	v14 = RecvLen;
	if (Len2 == 2)
		v16 = token->unknowToolID == 0xFBE0;
	if (v16 && pCmd[0] <= 9u && !pCmd[1])
		token->ToolID = tToolID;
	v17 = v26[0];
	v18 = 0x81 * v26[1];
	v19 = &token->AreaCode + 0x35D98 * v26[0] + 0x102 * v26[1];
	v19[0x10E26] = 2;
	result = 0;
	if (v14 < 0 || (unsigned __int16)v14 == 0xFF)
		return result;
	v21 = (unsigned __int8 *)(v19 + 0x10E26);
	v22 = (unsigned __int8 *)token + 0x35D98 * v17 + 2 * v18;
	v22[0x10E5C] = v14;                           // v22[0x10E5C]
	qmemcpy(v22 + 0x10E5D, RecvBuf, (unsigned __int8)v14);
	*v21 = 1;
LABEL_25:
	if ((__int16)v14 >= (int)(tlen - 1))
	{
		if (tlen < 2)
			return 1;
		v23 = 1;
		v24 = 1;
		while (!v28[v23] || (unsigned __int8)(v28[v23] & RecvBuf[v23 - 1]) == v27[v23])
		{
			v23 = (__int16)++v24;
			if ((__int16)v24 >= (int)tlen)
				return 1;
		}
	}
	return 0;
}





int SpecConditionOrderJudge(int constVal, int CompareVal, int FinalSelID, tt_Token *token, SpecInfoSt *SpecBuf)
{
	char **ArrEcuInfo; // r5
	__int16 Ret; // r11
	char *v11; // r4
	unsigned int v12; // r6
	int v13; // r8
	unsigned int v14[2]; // r2
	unsigned int v15; // r9
	int v16; // r6
	unsigned __int16 *v17; // r0
	unsigned __int16 *v18; // r0
	int v19; // t1
	int v20; // r11
	int v21; // r4
	int v22; // r0
	__int16 v23; // r0
	int v24; // r0
	__int16 v25; // r0
	int v26; // r0
	int tCompareVal; // [sp+14h] [bp-24h]
	unsigned int tConstVal; // [sp+1Ch] [bp-1Ch]
	unsigned int v30; // [sp+20h] [bp-18h]
	int v31; // [sp+24h] [bp-14h] BYREF

	v31 = 0;
	token->field_10E1C = 0;
	token->field_10E1E = 0;
	ArrEcuInfo = (char**)token->ArrEcuInfo;
	Ret = 0xFFFF;
	if (!(unsigned __int16)GetToyotaTblData(token->AreaCode, "Toyota_bin_17.bin", 0x17, token->ArrEcuInfo))
	{
		tCompareVal = CompareVal;
		tConstVal = constVal;
		v30 = FinalSelID;
		v11 = (char*)token->ArrEcuInfo[0x17];
		v12 = *(_DWORD *)(v11 + 2);
		v13 = *(_DWORD *)(v11 + 6) / v12;
		if (v12)
		{
			v14[0] = tConstVal;
			v14[1] = v30;
			v15 = 0;
			while (!*(_WORD *)&v11[v15 * v13 + 0x14])
			{
				if (++v15 >= v12)
					goto LABEL_8;
			}
			if (v15)
			{
			LABEL_8:
				v16 = 0;
				while (1)
				{
					v17 = (unsigned __int16 *)&v11[v16 * v13];
					v19 = v17[5];
					v18 = v17 + 5;
					if (v19 != tCompareVal || ((_BYTE)v18[6] & v14[0]) == 0 || v18[8] != v14[1])
						goto LABEL_29;
					v20 = v18[4];
					v21 = v18[1];
					if (v14[0] != 1)
					{
						v22 = v18[2];
						if (v22)
						{
							v23 = CmdCheckSupport(v22, &v31, 0, (EcuSt**)ArrEcuInfo, token);
							v14[0] = tConstVal;
							v14[1] = v30;
							if (!v20 || v23 || !v31)
								goto LABEL_29;
							goto LABEL_25;
						}
						if (v21)
						{
							v24 = GetCommFrameInfo(v21, (EcuSt**)ArrEcuInfo, token);
							v14[0] = tConstVal;
							v14[1] = v30;
							if (v24 < 0)
								goto LABEL_29;
							v25 = SendSpecCommand(token, SpecBuf, v24, v30);
							v14[0] = tConstVal;
							v14[1] = v30;
							if (!v20 || !v25)
								goto LABEL_29;
							goto LABEL_25;
						}
					}
					if (!v20)
						goto LABEL_29;
				LABEL_25:
					if (v14[0] == 2 && v20 == 1)
						SpecBuf->field_4C0 = 1;
					v26 = CheckUtilityList(v21, v20, token, SpecBuf);
					v14[0] = tConstVal;
					v14[1] = v30;
					if (v26 < 0)
						return 0xFFFF;
				LABEL_29:
					if (++v16 >= v15)
						return 0;
					v11 = (char*)token->ArrEcuInfo[0x17];
				}
			}
		}
	}
	return Ret;
}





int HideUtilFunc(int CompareVal, tt_Token *token)
{
	__int16 v4; // r0
	__int16 Ret; // r1
	EcuSt *v6; // r6
	unsigned int v7; // r5
	int v8; // r0
	char *v9; // r1
	int v10; // r2

	v4 = GetToyotaTblData(token->AreaCode, "Viewer_bin_11.bin", 0x11, token->ViewArrInfo);
	Ret = 0xFFFF;
	if (!v4)
	{
		v6 = token->ViewArrInfo[0x11];
		if (v6)
		{
			v7 = v6->SingleSize;
			v8 = v6->AllocSize / v7;
			if (v7)
			{
				v9 = &v6->field_A;
				v10 = 0;
				while (*(unsigned __int16 *)&v9[v10 * v8] != CompareVal || v9[v10 * v8 + 3])
				{
					if (++v10 >= v7)
						goto LABEL_8;
				}
				Ret = 1;
			}
			else
			{
			LABEL_8:
				Ret = 0;
			}
		}
	}
	return Ret;
}



int GetSpecFuncContent(int NumVal1, int NumVal2, tt_Token *token, SpecInfoSt *SpecBuf)
{
	EcuSt **ArrEcu; // r8
	__int16 Ret; // r9
	EcuSt *EcuInfo; // r10
	unsigned int v11; // r5
	int v12; // r4
	SpecInfoSt *tSpecBuf; // r12
	unsigned int v14; // r11
	__int16 v15; // r1
	int ttNumVal2; // r5
	int v17; // r9
	char *v18; // r0
	char *v19; // r0
	int v20; // t1
	int v21; // r0
	__int16 v22; // r0
	int v23; // r0
	int tNumVal1; // [sp+4h] [bp-24h]
	int tNumVal2; // [sp+Ch] [bp-1Ch]
	SpecInfoSt *pSepcBuf; // [sp+10h] [bp-18h]
	int v28; // [sp+14h] [bp-14h] BYREF

	v28 = 0;
	ArrEcu = token->ArrEcuInfo;
	Ret = 0xFFFF;
	if (!(unsigned __int16)GetToyotaTblData(token->AreaCode, "Toyota_bin_35.bin", 0x35, token->ArrEcuInfo))
	{
		tNumVal2 = NumVal2;
		pSepcBuf = SpecBuf;
		EcuInfo = token->ArrEcuInfo[0x35];
		v11 = EcuInfo->SingleSize;
		v12 = EcuInfo->AllocSize / v11;
		if (v11)
		{
			tSpecBuf = pSepcBuf;
			tNumVal1 = NumVal1;
			v14 = 0;
			while (!*(_WORD *)((char *)&EcuInfo[1].SingleSize + v14 * v12))
			{
				if (++v14 >= v11)
					goto LABEL_8;
			}
			if (!v14)
				return Ret;
		LABEL_8:
			v15 = 0;
			ttNumVal2 = tNumVal2;
			v17 = 0;
			while (1)
			{
				v18 = (char *)(&EcuInfo->EucIndex + v17 * v12);
				v20 = *((unsigned __int16 *)v18 + 5);
				v19 = v18 + 0xA;
				if (v20 == ttNumVal2 && v19[0xA] == tSpecBuf->field_4C0)
				{
					v21 = *((unsigned __int16 *)v19 + 2);
					if (!v21)
						goto LABEL_19;
					v22 = CmdCheckSupport(v21, &v28, 0, ArrEcu, token);
					v15 = 1;
					if (v22)
					{
						ttNumVal2 = tNumVal2;
						tSpecBuf = pSepcBuf;
					}
					else
					{
						ttNumVal2 = tNumVal2;
						tSpecBuf = pSepcBuf;
						if (v28 == 1)
							goto LABEL_19;
					}
				}
				if (++v17 >= v14)
					break;
				EcuInfo = token->ArrEcuInfo[0x35];
			}
			if (v15)
				goto LABEL_20;
		LABEL_19:
			tSpecBuf->SpecNumArr[tSpecBuf->SizeCount] = tNumVal1;
			v23 = tSpecBuf->SizeCount;
			tSpecBuf->SizeCount = v23 + 1;
			tSpecBuf->field_330[v23] = ttNumVal2;
		LABEL_20:
			Ret = 0;
		}
	}
	return Ret;
}





int CheckUtilityList(int a1, int a2, tt_Token *token, SpecInfoSt *SpecBuf)
{
	char **ArrEcu; // r10
	__int16 Ret; // r6
	EcuSt *v10; // r8
	unsigned int EcuData; // r5
	int SizeGroupNum; // r4
	unsigned int v13; // r9
	int Index; // r0
	int v15; // r8
	unsigned __int16 *v16; // r0
	unsigned __int16 *v17; // r0
	int v18; // r6
	int v19; // r10
	int v21; // [sp+0h] [bp-18h]
	SpecInfoSt *pSepcBuf; // [sp+4h] [bp-14h]
	int v23; // [sp+8h] [bp-10h]

	ArrEcu = (char **)token->ArrEcuInfo;
	Ret = 0xFFFF;
	if (!(unsigned __int16)GetToyotaTblData(token->AreaCode, "Toyota_bin_18.bin", 0x18, token->ArrEcuInfo))
	{
		v23 = a1;
		v21 = a2;
		v10 = token->ArrEcuInfo[0x18];
		EcuData = v10->SingleSize;
		SizeGroupNum = v10->AllocSize / EcuData;
		if (EcuData)
		{
			pSepcBuf = SpecBuf;
			v13 = 0;
			while (!*(_WORD *)((char *)&v10[1].AllocSize + v13 * SizeGroupNum))
			{
				if (++v13 >= EcuData)
					goto LABEL_8;
			}
			if (!v13)
				goto LABEL_16;
		LABEL_8:
			Index = GetCommFrameInfo(v23, (EcuSt**)ArrEcu, token);
			if (Index < 0)
				return 0;
			v15 = 0;
			pSepcBuf->field_4C0 = token->CmdInfoArr[Index].SysCmdBuf[0];
			while (1)
			{
				v16 = (unsigned __int16 *)(&token->ArrEcuInfo[0x18]->EucIndex + v15 * SizeGroupNum);
				if (v16[9] == v21)
				{
					v17 = v16 + 5;
					if (!*((_BYTE *)v17 + 0xF))
					{
						v18 = v17[5];
						v19 = *(_DWORD *)v17;
						if (!(unsigned __int16)HideUtilFunc(v18, token)
							&& GetSpecFuncContent(v19, v18, token, pSepcBuf) < 0)
						{
							break;
						}
					}
				}
				if (++v15 >= v13)
					return 0;
			}
		LABEL_16:
			Ret = 0xFFFF;
		}
	}
	return Ret;
}


int P5_SendCmdCreateEnableDIdList(int a1, DSInofo4C *Ds4CInfo, tt_Token *token)
{
	int v5; // r0
	CmdInfoSt22 *v6; // r0
	size_t Len; // r5 MAPDST
	unsigned int v8; // r1
	unsigned int v9; // r0
	int *v10; // r1
	size_t v12; // r5
	size_t v13; // r4
	int v14; // r8
	int v15; // r0
	signed __int16 v16; // r10
	unsigned int v17; // r1
	unsigned int v18; // r0
	int v19; // r1
	__int16 v20; // r0
	size_t v21; // r11
	int v23; // [sp+Ch] [bp-164h]
	int v25; // [sp+20h] [bp-150h]
	unsigned __int8 RcvBuf[256]; // [sp+28h] [bp-148h] BYREF
	unsigned __int8 CmdBuf[56]; // [sp+128h] [bp-48h] BYREF

	memset(CmdBuf, 0, 0x32u);
	memset(RcvBuf, 0, 0xFFu);

	v5 = GetFuncCommFrameInfo(200, a1, token->ArrEcuInfo, token);
	if (v5 < 0)
		return -1;
	v6 = (CmdInfoSt22 *)((char *)token + 258 * v5);
	Len = v6[13].CmdLen6;
	qmemcpy(CmdBuf, v6[13].CmdBuf8, Len);
	memset(RcvBuf, 0, 0xFFu);
	v8 = *(unsigned __int16 *)&token->InitCommMode;
	v9 = v8 >> 8;
	if ((unsigned __int8)v8 == 3)
		v10 = (int *)P5_SendCmdGetReceive;
	else
		v10 = (int *)SendCmdAndGetReceive;
	v23 = (*(__int16(__fastcall **)(unsigned __int8 *, int, tt_Token *, unsigned __int8 *, size_t, unsigned int, _DWORD))*v10)(
		RcvBuf,
		255,
		token,
		CmdBuf,
		Len,
		v9,
		0);
	if (v23 >= 0)
	{
		v12 = (unsigned __int8)(v23 - 2);
		if (v12 > 0x20)
			v12 = 32;
		memmove(RcvBuf, &RcvBuf[2], v12);
		v23 = 0;
		P5_DidAnalyzeFrameData(0, RcvBuf, v12, 8, 47, Ds4CInfo);
		v25 = Ds4CInfo->loopCount;
		if (v25 >= 1)
		{
			v13 = Len;
			v14 = 0;
			v15 = 0;
			do
			{
				v16 = Ds4CInfo->field_1C[v15];
				CmdBuf[1] = HIBYTE(v16);
				CmdBuf[2] = v16;
				memset(RcvBuf, 0, 0xFFu);
				v17 = *(unsigned __int16 *)&token->InitCommMode;
				v18 = v17 >> 8;
				if ((unsigned __int8)v17 == 3)
					v19 = (int)&P5_SendCmdGetReceive;
				else
					v19 = (int)&SendCmdAndGetReceive;
				v20 = (*(int(__fastcall **)(unsigned __int8 *, int, tt_Token *, unsigned __int8 *, size_t, unsigned int, _DWORD))v19)(
					RcvBuf,
					255,
					token,
					CmdBuf,
					v13,
					v18,
					0);
				if (v20 >= 0)
				{
					v21 = (unsigned __int8)(v20 - 2);
					if (v21 > 0x20)
						v21 = 32;
					memmove(RcvBuf, &RcvBuf[2], v21);
					v13 = Len;
					P5_DidAnalyzeFrameData(v16, RcvBuf, v21, 0, 47, Ds4CInfo);
				}
				v15 = (__int16)++v14;
			} while ((__int16)v14 < v25);
			return 0;
		}
	}
	return v23;
}




int P5SpecFuncListCheckSupportUrid(int NumVal1, int NUmVal2, int *FlagNum, int ConstNum, int *SysData)
{
	unsigned int v5; // lr
	int v6; // r4
	unsigned int v7; // r3
	int v8; // r0
	int v9; // r5
	char v10; // r0
	int v11; // r1
	int v12; // r0

	*FlagNum = 0;
	if (NumVal1)
	{
		v5 = SysData[0x10];
		if (v5)
		{
			v6 = 0;
			while (*(unsigned __int16 *)(SysData[0x11] + 2 * v6) != NUmVal2)
			{
				if (++v6 >= v5)
					goto LABEL_6;
			}
			v11 = *(unsigned __int8 *)(SysData[0x12] + v6);
			if (*(_BYTE *)(SysData[0x12] + v6))
				v11 = 1;
			*FlagNum = v11;
			if (ConstNum == 1)
			{
				v12 = *(unsigned __int8 *)(NumVal1 + 0x24);
				if (v12)
				{
					if (v12 != 1)
						v12 = 0;
					*FlagNum = v12;
				}
			}
		}
		else
		{
		LABEL_6:
			v7 = SysData[0xE];
			if (v7)
			{
				v8 = *(unsigned __int16 *)(NumVal1 + 0x10);
				v9 = 0;
				while (*(unsigned __int16 *)(SysData[0xF] + 2 * v9) != v8)
				{
					if (++v9 >= v7)
						goto LABEL_10;
				}
				v10 = 1;
				*FlagNum = 1;
				v5 = SysData[0x10];
			}
			else
			{
			LABEL_10:
				v10 = 0;
			}
			*(_WORD *)(SysData[0x11] + 2 * v5) = NUmVal2;
			*(_BYTE *)(SysData[0x12] + v5) = v10;
			++SysData[0x10];
		}
	}
	return 0;
}





int GetSpecFuncList(tt_Token *token, SpecInfoSt *SpecBuf)
{
	int FinalSel; // r6
	__int16 Ret; // r8

	SpecBuf->SizeCount = 0;
	SpecBuf->xxNum = 0;
	FinalSel = (unsigned __int16)token->FinalSelID;
	Ret = 0xFFFF;
	if (SpecConditionOrderJudge(
		4,
		LOWORD(token->SysInfoArr[token->SysListCanUseNum].offset),
		FinalSel,
		token,
		SpecBuf) >= 0
		&& SpecConditionOrderJudge(2, 0, FinalSel, token, SpecBuf) >= 0)
	{
		GetPlusP5SpecFuncList(LOWORD(token->SysInfoArr[token->SysListCanUseNum].offset), token, SpecBuf);
		Ret = 0;
	}
	return Ret;
}


unsigned __int16 GetPlusP5SpecFuncList(int CompareVal, tt_Token *token, SpecInfoSt *SpecBuf)
{
	return 1;
}